package com.example;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoop;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioChannelOption;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.LineBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.timeout.IdleStateHandler;

import java.net.InetSocketAddress;
import java.util.concurrent.TimeUnit;

public class NettyStarter {

    private String host="127.0.0.1";
    private int port=5510;

    private boolean isStart = false;

    Bootstrap bootstrap = new Bootstrap();
    private EventLoopGroup workGroup = new NioEventLoopGroup();

    public void clientStart() {

        if (isStart) {return;}

        workGroup = new NioEventLoopGroup();

        bootstrap = new Bootstrap();
        bootstrap.channel(NioSocketChannel.class);
        bootstrap.group(workGroup);
        bootstrap.option(NioChannelOption.SO_REUSEADDR, true)
                .option(NioChannelOption.TCP_NODELAY, true)
                .option(NioChannelOption.SO_KEEPALIVE, true);
//        bootstrap.handler();
        ClientHandler ch = new ClientHandler(this);
        bootstrap.handler(new ChannelInitializer<SocketChannel>() {
            @Override
            protected void initChannel(SocketChannel socketChannel) throws Exception {
                socketChannel.pipeline().addLast(new IdleStateHandler(5, 5, 5));
                socketChannel.pipeline().addLast(new LineBasedFrameDecoder(1024));
                socketChannel.pipeline().addLast(new StringDecoder());
                socketChannel.pipeline().addLast(new StringEncoder());
                socketChannel.pipeline().addLast(ch);
            }
        });
        bootstrap.remoteAddress(new InetSocketAddress(host, port));
        doConnect();
    }

    public void doConnect() {
        bootstrap.connect().addListener((ChannelFuture f) -> {
            if (!f.isSuccess()) {
                System.out.println("连接服务端失败，5s后重连...");
                final EventLoop loop = f.channel().eventLoop();
                loop.schedule(new Runnable() {
                    @Override
                    public void run() {
                        doConnect();
                    }
                }, 5L, TimeUnit.SECONDS);
            } else {
                System.out.println("建立连接，连接服11务端成功！");
                isStart = true;
            }
        });
    }

    public synchronized void clientStop() {
        try {
            if (!isStart) return;

            System.out.println("关闭连接！");
            workGroup.shutdownGracefully().sync();
            isStart = false;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        NettyStarter nettyStarter = new NettyStarter();
        nettyStarter.clientStart();
    }
}